package message

import (
	"context"
	"net/http"

	"github.com/gin-gonic/gin"

	"mxshop-api/shared/auth"
	"mxshop-api/userop-web/api"
	"mxshop-api/userop-web/forms"
	"mxshop-api/userop-web/global"
	proto "mxshop-api/userop-web/proto/userop/gen/v1"
)

type APIMsg struct {
	ID             int32  `json:"id,omitempty"`
	UserId         int32  `json:"user_id,omitempty"`
	MessageType    int32  `json:"message_type,omitempty"`
	MessageTypeStr string `json:"message_type_str,omitempty"`
	Subject        string `json:"subject,omitempty"`
	Message        string `json:"message,omitempty"`
	File           string `json:"file,omitempty"`
}

func EntityPbToAPIMsg(m *proto.MessageEntity) APIMsg {
	return APIMsg{
		ID:             m.Id,
		UserId:         m.Message.UserId,
		MessageType:    int32(m.Message.MessageType),
		MessageTypeStr: m.Message.MessageType.String(),
		Subject:        m.Message.Subject,
		Message:        m.Message.Message,
		File:           m.Message.File,
	}
}

func ValueObjToPb(userID int32, m forms.MessageForm) *proto.Message {
	return &proto.Message{
		UserId:      userID,
		MessageType: proto.MsgType(m.MessageType),
		Subject:     m.Subject,
		Message:     m.Message,
		File:        m.File,
	}
}

func New(c *gin.Context) {
	userID, err := auth.UserIDFromContext(c)
	if err != nil {
		return
	}

	var messageForm forms.MessageForm
	err = c.ShouldBind(&messageForm)
	if err != nil {
		api.HandleValidatorError(c, err)
		return
	}

	userOpCli := proto.NewMessageServiceClient(global.UserOpConn)
	message, err := userOpCli.CreateMessage(context.Background(), ValueObjToPb(int32(userID), messageForm))
	if err != nil {
		api.HandleGrpcErrorToHttp(c, err)
		return
	}

	c.JSON(http.StatusCreated, EntityPbToAPIMsg(message))
}

func List(c *gin.Context) {
	claims, err := auth.ClaimsFromContext(c)
	if err != nil {
		return
	}

	var msgFilter = proto.MessageListRequest{}
	switch claims.RoleID {
	case 1:
		msgFilter.UserId = int32(claims.ID)
	case 2:
	default:
		c.Status(http.StatusForbidden)
		return
	}

	userOpCli := proto.NewMessageServiceClient(global.UserOpConn)
	msgListResp, err := userOpCli.MessageList(context.Background(), &msgFilter)
	if err != nil {
		api.HandleGrpcErrorToHttp(c, err)
		return
	}

	messages := make([]APIMsg, 0, len(msgListResp.Messages))
	for _, message := range msgListResp.Messages {
		messages = append(messages, EntityPbToAPIMsg(message))
	}

	c.JSON(http.StatusOK, gin.H{
		"total": msgListResp.Total,
		"data":  messages,
	})
}
